/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package indexer;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

/**
 *
 * @author Claudiu
 */
public class SearchInInverseIndex {

    String inverseIndexCodingFileName;
    String inverseIndexFileName;
    public int[] searchResponseDocumentList;
    public String[] responseWords;
    public ArrayList<Integer> hashArray;
    public int nr_words;

    public SearchInInverseIndex(String _inverseIndexFileName, String _inverseIndexCoding) {
        inverseIndexCodingFileName = _inverseIndexCoding;
        inverseIndexFileName = _inverseIndexFileName;
        searchResponseDocumentList = new int[30000];
        responseWords = new String[1000];
        hashArray = new ArrayList<Integer>();
        nr_words = 0;

    }

    int[] getDocumentIDs(int[] hashCode) {
        int[] returnArray = new int[1];
        try {
            FileReader reader = new FileReader(inverseIndexFileName);
            BufferedReader input = new BufferedReader(reader);
            String line = input.readLine();
            String unsplitDocumentList = " ";
            while (line != null) {
                String[] split = new String[30];
                split = line.split(":");
                String word1 = split[0];
                try {
                    if (word1.length() > 2) {
                        int extractedHashCode = Integer.parseInt(word1.trim());
                        for (int i = 0; i < nr_words; i++) {
                            if (hashCode[i] == extractedHashCode || hashCode[i] == -extractedHashCode) {
                                unsplitDocumentList += split[1].trim();
                                   System.out.println("*---*");
                                   System.out.println(unsplitDocumentList);
                            }
                        }
                    }
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                }

                line = input.readLine();
            }

            try {
                String[] split /*= new String[10000]*/;

                System.out.println("*---*");
                System.out.println("++"+unsplitDocumentList);
                split = unsplitDocumentList.split(",");
                 returnArray = new int[split.length];
                for (int i = 0; i < split.length; i++) {

               // if (split[i].length() > 2) {
                        returnArray[i] = Integer.parseInt(split[i].trim());
                  //  } else {
                        
                    }
           //     }

            } catch (Exception e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return returnArray;
    }

    public void parseToArray() {
        try {
            FileReader reader = new FileReader(inverseIndexCodingFileName);
            BufferedReader input = new BufferedReader(reader);
            String line = input.readLine();
            while (line != null) {
                String[] split = new String[30];
                split = line.split(":");
                String word1 = split[0];
                int wordId = 0;
                if (split[1].length() > 2) {
                    wordId = Integer.parseInt(split[1].trim());
                }
                hashArray.add(wordId);
                line = input.readLine();
            }
            HashSet<Integer> temp = new HashSet<Integer>(hashArray);
            int[] a = new int[100000];
            for (int i = 0; i < hashArray.size(); i++) {
                a[i] = hashArray.get(i);
            }
            Arrays.sort(a);
            for (int i = 0; i < hashArray.size(); i++) {
                hashArray.set(i, a[i]);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    public int binSearchHashCode(int value, int low, int high) {
        try {
            int return_val;

            if (high < low) {
                return -1;
            }
            int mid = low + (high - low) / 2;
            if (hashArray.get(mid) > value) {
                return binSearchHashCode(value, low, mid - 1);
            } else if (hashArray.get(mid) < value) {
                return binSearchHashCode(value, mid + 1, high);
            } else {
                return mid;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
            return -1;
        }
    }

    public void printSimilars(String word) {
        printSimilars(word.hashCode());
    }

    public void printSimilars(int hashCode) {
        getDocumentIDs(getSimilarHashCode(hashCode));
    }

    public int[] getSimilarHashCode(int hashcode) {
        int[] returnArray = new int[15];
        try {
            parseToArray();

            int val = binSearchHashCode(hashcode, 0, hashArray.size() - 1);
            int goVal;
            //if (val != -1) {
            //   goVal = hashArray.get(val);
            //  System.out.println("1 go val : " + goVal);
            //} else {
            goVal = closestLarger(hashcode);
            System.out.println("2 go val : " + goVal);
            //}
            // goVal= hashArray.indexOf(goVal);
            System.out.println("go val : " + goVal);

            if ((goVal > 1) && (goVal < hashArray.size() - 2)) {
                returnArray[0] = hashArray.get(goVal - 2);
                returnArray[1] = hashArray.get(goVal - 1);
                returnArray[2] = hashArray.get(goVal - 0);
                returnArray[3] = hashArray.get(goVal + 1);
                returnArray[4] = hashArray.get(goVal + 2);
            } else {
                if (goVal > 1) {
                    returnArray[0] = hashArray.get(goVal - 4);
                    returnArray[1] = hashArray.get(goVal - 3);
                    returnArray[2] = hashArray.get(goVal - 2);
                    returnArray[3] = hashArray.get(goVal - 1);
                    returnArray[4] = hashArray.get(goVal);
                } else {
                    //returnArray[0] = hashArray.get(goVal);
                    returnArray[1] = hashArray.get(goVal + 1);
                    returnArray[2] = hashArray.get(goVal + 2);
                    returnArray[3] = hashArray.get(goVal + 3);
                    returnArray[4] = hashArray.get(goVal + 4);
                }
            }
            int[] rpk = getDocumentIDs(returnArray);
            int aux = 0;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return returnArray;
    }

    public int[] getSimilarHashCodes(String word) {
        return getSimilarHashCode(word.hashCode());
    }

    public int closestLarger(int hashCode) {
        try {
            for (int i = 0; i < hashArray.size() - 1; i++) {
                if (hashArray.get(i) <= hashCode && hashArray.get(i + 1) >= hashCode) {
                    return i;
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return -1;
    }

    public void searchWord(String word) {

        String word1 = "-=";
        try {
            FileReader reader = new FileReader(inverseIndexCodingFileName);
            BufferedReader input = new BufferedReader(reader);
            String line = input.readLine();
            while (line != null) {
                String[] split = new String[30];
                split = line.split(" : ");
                word1 = split[0].trim();

                if (word1.trim().length() > 4) {
                    int wordId = Integer.parseInt(split[1].trim());
                    if (wordCosine(word1, word)) {
                        searchResponseDocumentList[nr_words] = wordId;
                        responseWords[nr_words] = word1;
                        System.out.println("potential match : " + word1);
                        nr_words++;
                    }
                }
                line = input.readLine();

            }
            input.close();
        } catch (Exception ex) {
            System.out.println("exception searchInverseIndex" + nr_words + "    " + word1);
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
    }

    public boolean wordCosine(String word1, String word2) {
        int ax1 = 2 * word1.length() / 3;
        int ax2 = 2 * word2.length() / 3;
        if (ax1 < 5) {
            ax1 = 5;
            if (ax1 > word1.length()) {
                ax1 = word1.length() - 2;
            }
        }
        if (ax1 < 5) {
            ax2 = 5;
            if (ax2 > word2.length()) {
                ax2 = word2.length() - 2;
            }
        }
        try {
            String piece1 = word1.substring(0, ax1);
            String piece2 = word2.substring(0, ax2);
            if( (word1.contains(piece2) || word2.contains(piece1) )&&(ax1>4 && ax2 >4) ){
                return true;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        // String a1 = word1.substring(nr_words, nr_words);
        String a2;
        if (word1.contains(word2)) {
            return true;
        } else {
            if (word2.contains(word1)) {
                return true;
            } else {
                boolean similar = false;

                int len1 = word1.length();
                int len2 = word2.length();
                int len = len2;
                if (len1 < len2) {
                    len = len1;
                }
                double distance = 0;
                double sumTop = 0;
                double firstSumBtm = 0;
                double lastSumBtm = 0;
                for (int i = 0; i < len; i++) {
                    sumTop += (((word1.charAt(i) - 'A')) * ((word2.charAt(i) - 'A'))) * i;
                    firstSumBtm += (((word1.charAt(i) - 'A')) * ((word1.charAt(i) - 'A'))) * i;
                    lastSumBtm += (((word2.charAt(i) - 'A')) * ((word2.charAt(i) - 'A'))) * i;
                }
                distance = (sumTop / (Math.sqrt(firstSumBtm) * Math.sqrt(lastSumBtm)));
           //     System.out.println("   " + distance + "        " + word1 + "       " + word2 + "    " + Math.sqrt(firstSumBtm) + " " + Math.sqrt(lastSumBtm) + "   " + sumTop);
                if (distance ==  0.99) {
                    similar = true;
                } else {
                    //  similar = false;
                }
                return similar;
            }
        }
    }
}
